package o2o.service.company.postman;

import com.jinyou.utils.common.DateUtils;
import com.jinyou.utils.common.ValidateUtil;
import com.jinyouapp.common.tools.jms.model.JMSNotify;
import o2o.cache.company.postman.PostCompanyMemory;
import o2o.config.dao.UserDaoSql;
import o2o.config.jms.config.JMSTypeContent;
import o2o.config.jms.sender.JmsSender;
import o2o.dao.PO.PojoTables;
import o2o.dao.PO.company.postman.*;
import o2o.dao.PO.user.UserInfo;
import o2o.dao.TO.sign.ShopSignCompanyFeeTO;
import o2o.dao.TO.sign.ShopSignCompanyTO;
import o2o.dao.TO.sync.ShopSignDeliverComMoneyTO;
import o2o.dao.TO.sync.ShopSignDeliverComTO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Jahnke【1029777564@qq.com】
 * @ClassName ShopSignCompanyService
 * @Description:
 * @date 2019/8/8 11:24
 * @Version 1.0
 */
public class ShopSignCompanyService {

    private ShopSignCompanyService() {
    }

    enum Singleton {
        INSTANCE;
        private ShopSignCompanyService single;

        private Singleton() {
            single = new ShopSignCompanyService();
        }

        private ShopSignCompanyService getInstance() {
            return single;
        }
    }

    public static ShopSignCompanyService getInstance() {
        return Singleton.INSTANCE.single;
    }

    // 添加或者更新商户和配送公司的签约关系
    public boolean addOrUpdate(List<ShopSignDeliverComTO> list) throws SQLException {
        Connection conn = UserDaoSql.getInstance().getConnection();
        conn.setAutoCommit(false);
        try {
            for (int i = 0; i < list.size(); i++) {
                // 首先更新商户和配送公司信息
                ShopSignCompanyInfo info = list.get(i).convert2Info();
                String sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY + " where companyId=" + info.getCompanyId() + " and shopId=" + info.getShopId() + " and delFlag = 0";
                ShopSignCompanyInfo dbInfo = (ShopSignCompanyInfo) UserDaoSql.getInstance().getObject(ShopSignCompanyInfo.class, sql);
                // 删除配送费信息
                String delm = "delete from " + PojoTables.SHOP_SIGN_COMPANY_FEE + " where companyId=" + info.getCompanyId() + " and shopId=" + info.getShopId();
                UserDaoSql.getInstance().executeBySql(delm, conn);
                if (dbInfo == null) {
                    // 直接添加
                    UserDaoSql.getInstance().saveObj(PojoTables.SHOP_SIGN_COMPANY, info, conn);

                    // 遍历商户和配送公司约定的配送费
                    List<ShopSignDeliverComMoneyTO> ll = list.get(i).getDeliveryMoney();
                    for (int j = 0; j < ll.size(); j++) {
                        ShopSignCompanyFeeInfo feeInfo = ll.get(j).convert2Info(info.getShopId(), info.getCompanyId());
                        if (feeInfo != null) {
                            UserDaoSql.getInstance().saveObj(PojoTables.SHOP_SIGN_COMPANY_FEE, feeInfo, conn);
                        }
                    }
                    this.clearCache(info.getCompanyId(), info.getShopId());
                    try {
                        // 数据通讯
                        JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_CLEAN)
                                .setLong01(info.getCompanyId()).setLong02(info.getShopId());
                        JmsSender.setTopicSender(notify);
                    } catch (Exception e) {
                    }
                } else {
                    // 更新商户和配送公司的配送费(签约状态不变)
                    if (dbInfo.getStatus() != SIGN_COMPANY_STATUS.pass) {
                        String updateSql = "update " + PojoTables.SHOP_SIGN_COMPANY + " set status =" + SIGN_COMPANY_STATUS.apply + " where delFlag = and id =" + dbInfo.getId();
                        UserDaoSql.getInstance().executeBySql(updateSql.toString(), conn);
                    }
                    List<ShopSignDeliverComMoneyTO> ll = list.get(i).getDeliveryMoney();
                    for (int j = 0; j < ll.size(); j++) {
                        ShopSignCompanyFeeInfo feeInfo = ll.get(j).convert2Info(info.getShopId(), info.getCompanyId());
                        if (feeInfo != null) {
                            UserDaoSql.getInstance().saveObj(PojoTables.SHOP_SIGN_COMPANY_FEE, feeInfo, conn);
                        }
                    }
                    this.clearCache(info.getCompanyId(), info.getShopId());
                    try {
                        // 数据通讯
                        JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_CLEAN)
                                .setLong01(info.getCompanyId()).setLong02(info.getShopId());
                        JmsSender.setTopicSender(notify);
                    } catch (Exception e) {
                    }
                }

            }
            // 更新缓存
            conn.commit();
        } catch (Exception e) {
            UserDaoSql.getInstance().rollback(conn);
            return false;
        } finally {
            UserDaoSql.getInstance().close(conn);
        }
        for (ShopSignDeliverComTO to : list) {
            this.updateCacheOfShopSign(to.getShopId());
            try {
                // 数据通讯
                JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_MODIFY)
                        .setLong01(to.getShopId());
                JmsSender.setTopicSender(notify);
            } catch (Exception e) {
            }
        }
        return true;
    }

    // 添加或者更新商户和配送公司的签约关系
    public boolean addOrUpdateV2(ShopSignCompanyInfo info, List<ShopSignDeliverComMoneyTO> ll) throws SQLException {
        Connection conn = UserDaoSql.getInstance().getConnection();
        conn.setAutoCommit(false);
        try {
            // 首先更新商户和配送公司信息
            // ShopSignCompanyInfo info = signDeliverComTO.convert2Info();
            String sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY + " where companyId=" + info.getCompanyId() + " and shopId=" + info.getShopId() + " and delFlag = 0";
            ShopSignCompanyInfo dbInfo = (ShopSignCompanyInfo) UserDaoSql.getInstance().getObject(ShopSignCompanyInfo.class, sql);
            // 删除配送费信息
            String delm = "update " + PojoTables.SHOP_SIGN_COMPANY_FEE + " set delFlag = 1 where companyId=" + info.getCompanyId() + " and shopId=" + info.getShopId();
            UserDaoSql.getInstance().executeBySql(delm, conn);
            if (dbInfo == null) {
                // 直接添加
                UserDaoSql.getInstance().saveObj(PojoTables.SHOP_SIGN_COMPANY, info, conn);
                // 遍历商户和配送公司约定的配送费
                // List<ShopSignDeliverComMoneyTO> ll = signDeliverComTO.getDeliveryMoney();
                if (ValidateUtil.isAbsList(ll)) {
                    for (int j = 0; j < ll.size(); j++) {
                        ShopSignCompanyFeeInfo feeInfo = ll.get(j).convert2Info(info.getShopId(), info.getCompanyId());
                        if (feeInfo != null) {
                            UserDaoSql.getInstance().saveObj(PojoTables.SHOP_SIGN_COMPANY_FEE, feeInfo, conn);
                        }
                    }
                }
                this.clearCache(info.getCompanyId(), info.getShopId());
                try {
                    // 数据通讯
                    JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_CLEAN)
                            .setLong01(info.getCompanyId()).setLong02(info.getShopId());
                    JmsSender.setTopicSender(notify);
                } catch (Exception e) {
                }
            } else {
                // 更新商户和配送公司的配送费(签约状态不变)
                if (dbInfo.getStatus() != SIGN_COMPANY_STATUS.pass) {
                    String updateSql = "update " + PojoTables.SHOP_SIGN_COMPANY + " set status =" + SIGN_COMPANY_STATUS.apply + " where delFlag =0 and id =" + dbInfo.getId();
                    UserDaoSql.getInstance().executeBySql(updateSql.toString(), conn);
                }
                if (ValidateUtil.isAbsList(ll)) {
                    for (int j = 0; j < ll.size(); j++) {
                        ShopSignCompanyFeeInfo feeInfo = ll.get(j).convert2Info(info.getShopId(), info.getCompanyId());
                        if (feeInfo != null) {
                            UserDaoSql.getInstance().saveObj(PojoTables.SHOP_SIGN_COMPANY_FEE, feeInfo, conn);
                        }
                    }
                }
                this.clearCache(info.getCompanyId(), info.getShopId());
                try {
                    // 数据通讯
                    JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_CLEAN)
                            .setLong01(info.getCompanyId()).setLong02(info.getShopId());
                    JmsSender.setTopicSender(notify);
                } catch (Exception e) {
                }
            }
            // 更新缓存
            conn.commit();
        } catch (Exception e) {
            UserDaoSql.getInstance().rollback(conn);
            return false;
        } finally {
            UserDaoSql.getInstance().close(conn);
        }
        this.updateCacheOfShopSign(info.getShopId());
        try {
            // 数据通讯
            JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_MODIFY)
                    .setLong01(info.getShopId());
            JmsSender.setTopicSender(notify);
        } catch (Exception e) {
        }
        return true;
    }

    // 添加或者更新商户和配送公司的签约关系
    public boolean addOrUpdateV2(ShopSignCompanyInfo info, String opUser) throws SQLException {
        Connection conn = UserDaoSql.getInstance().getConnection();
        conn.setAutoCommit(false);
        try {
            this.updateCacheOfShopSign(info.getShopId());
            String sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY + " where companyId=" + info.getCompanyId() + " and shopId=" + info.getShopId() + " and delFlag = 0";
            ShopSignCompanyInfo dbInfo = (ShopSignCompanyInfo) UserDaoSql.getInstance().getObject(ShopSignCompanyInfo.class, sql);
            if (dbInfo == null) {
                // 直接添加
                info.setApplyTime(DateUtils.getCurrTime());
                info.setCreateTime(DateUtils.getCurrTime());
                info.setStatus(SIGN_COMPANY_STATUS.apply);
                UserDaoSql.getInstance().saveObj(PojoTables.SHOP_SIGN_COMPANY, info, conn);
                this.clearCache(info.getCompanyId(), info.getShopId());
                try {
                    // 数据通讯
                    JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_CLEAN)
                            .setLong01(info.getCompanyId()).setLong02(info.getShopId());
                    JmsSender.setTopicSender(notify);
                } catch (Exception e) {
                }
            } else {
                StringBuffer updateSql = new StringBuffer();
                updateSql.append(" update ").append(PojoTables.SHOP_SIGN_COMPANY)
                        .append(" set ").append("  applyTime =").append(DateUtils.getCurrTime())
                        .append(" ,updateUser = '").append(opUser).append("'")
                        .append(",companyShareRate =").append(info.getCompanyShareRate())
                        .append(", status = ").append(SIGN_COMPANY_STATUS.apply)
                        .append(" where id =").append(dbInfo.getId()).append(" and delFlag = 0");
                UserDaoSql.getInstance().executeBySql(updateSql.toString(), conn);
            }
            conn.commit();
        } catch (Exception e) {
            e.printStackTrace();
            UserDaoSql.getInstance().rollback(conn);
        } finally {
            UserDaoSql.getInstance().close(conn);
        }
        return true;
    }


    public Map<String, List<ShopSignCompanyFeeInfo>> dataMap = new ConcurrentHashMap<>();

    // 获取商户和配送公司关于某种配送类型的配送费
    public ShopSignCompanyFeeInfo get(Long companyId, Long shopId, int postType) {
        String key = companyId + "-" + shopId;
        if (dataMap.containsKey(key)) {
            List<ShopSignCompanyFeeInfo> list = dataMap.get(key);
            ShopSignCompanyFeeInfo info = this.get(list, postType);
            if (info != null) {
                return info;
            }
        }
        // 查询数据库
        String sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY_FEE + " where companyId=" + companyId + " and shopId=" + shopId;
        try {
            List<ShopSignCompanyFeeInfo> ll = (List<ShopSignCompanyFeeInfo>) UserDaoSql.getInstance().list(ShopSignCompanyFeeInfo.class, sql);
            if (ll != null && !ll.isEmpty()) {
                dataMap.put(key, ll);
            }
            return this.get(ll, postType);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 获取商户和配送公司关于某种配送类型的配送费
    public List<ShopSignCompanyFeeInfo> list(Long companyId, Long shopId) {
        String key = companyId + "-" + shopId;
        List<ShopSignCompanyFeeInfo> list = null;
        if (dataMap.containsKey(key)) {
            list = dataMap.get(key);
        }
        if (list == null || list.isEmpty()) {
            // 查询数据库
            String sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY_FEE + " where companyId=" + companyId + " and shopId=" + shopId;
            try {
                list = (List<ShopSignCompanyFeeInfo>) UserDaoSql.getInstance().list(ShopSignCompanyFeeInfo.class, sql);
                if (list != null && !list.isEmpty()) {
                    dataMap.put(key, list);
                }
                return list;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return list;
    }

    // 获取某个公司的签约的店铺数量
    public Long countOfCompanyIdAndType(long companyId) {
        StringBuilder countSql = new StringBuilder();
        countSql.append("select count(*) as counts from ").append(PojoTables.SHOP_SIGN_COMPANY)
                .append(" where delFlag = 0 and companyId = ").append(companyId);
        long count = 0L;
        try {
            count = UserDaoSql.getInstance().getCount(countSql.toString());
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
        return count;
    }

    // 重新更新缓存
    public void clearCache(Long companyId, Long shopId) {
        String key = companyId + "-" + shopId;
        if (dataMap.containsKey(key)) {
            dataMap.remove(key);
        }
    }

    // 获取配送公司的签约商户列表
    public List<ShopSignCompanyInfo> list(Long companyId, Integer status) {
        String sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY + " where delFlag=0 and status=" + status + " and companyId=" + companyId;
        List<ShopSignCompanyInfo> list = null;
        try {
            list = (List<ShopSignCompanyInfo>) UserDaoSql.getInstance().list(ShopSignCompanyInfo.class, sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return list;
    }

    private static Map<String, List<ShopSignCompanyInfo>> shopSignMap = new ConcurrentHashMap<>();

    // 获取店铺的签约信息
    public List<ShopSignCompanyTO> listOfCompany(Long shopId) {
        String key = null;
        List<ShopSignCompanyInfo> ll = this.listSignByShopId(shopId);
        List<ShopSignCompanyTO> re = null;
        if (ll != null && !ll.isEmpty()) {
            re = new ArrayList<>();
            for (int i = 0; i < ll.size(); i++) {
                PostCompanyInfo postCompanyInfo = PostCompanyMemory.getInstance().getById(ll.get(i).getCompanyId());
                if (postCompanyInfo != null) {
                    ShopSignCompanyTO to = new ShopSignCompanyTO();
                    BeanUtils.copyProperties(ll.get(i), to);
                    to.setCompanyName(postCompanyInfo.getCompanyName());

                    // 获取配送公司和商户的配送类型费用
                    List<ShopSignCompanyFeeInfo> fees = this.list(ll.get(i).getCompanyId(), shopId);
                    if (fees != null && !fees.isEmpty()) {
                        for (int j = 0; j < fees.size(); j++) {
                            ShopSignCompanyFeeTO tt = new ShopSignCompanyFeeTO();
                            BeanUtils.copyProperties(fees.get(j), tt);
                            to.getFees().add(tt);
                        }
                    }
                    re.add(to);
                }

            }
        }
        return re;
    }

    public ShopSignCompanyInfo getSignInfo(Long companyId, Long shopId) {
        List<ShopSignCompanyInfo> listSign = this.listSignByShopId(shopId);
        try {
            return listSign == null ? null : listSign.stream().filter(a -> a.getCompanyId().equals(companyId)).findAny().get();
        } catch (Exception e) {
            return null;
        }
    }

    // 获取商家所有的签约信息
    public List<ShopSignCompanyInfo> listSignByShopId(Long shopId, Set<Integer> signStatus) {
        // String key = null;
        // 查询数据库
        String sql = "";
        if (signStatus != null && signStatus.size() > 0) {
            sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY + " where delFlag=0 and status in (" + StringUtils.join(signStatus, ",") + ") and shopId=" + shopId;
        } else {
            sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY + " where delFlag=0 and shopId=" + shopId;
        }
        List<ShopSignCompanyInfo> list = null;
        try {
            list = (List<ShopSignCompanyInfo>) UserDaoSql.getInstance().list(ShopSignCompanyInfo.class, sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // if (list != null && !list.isEmpty()) {
        //     shopSignMap.put(key, list);
        // }
        return list == null ? Collections.emptyList() : list;
    }

    // 更新商户和公司的关系-最近的结算日期
    public void updateShopAndComLastJsDate(Long companyId, Long shopId, Long time) throws Exception {
        // 更改商户的本次结算日期
        ShopSignCompanyInfo shopSignCompanyInfo = ShopSignCompanyService.getInstance().getSignInfo(companyId, shopId);
        if (shopSignCompanyInfo == null) {
            throw new Exception("未查询到有效的商户签约信息");
        }
        String sql = "update " + PojoTables.SHOP_SIGN_COMPANY + " set lastAccountDate='" + (DateUtils.sdfDateTime.get().format(time)) + "'" + " where companyId=" + companyId + " and shopId=" + shopId;
        UserDaoSql.getInstance().executeBySql(sql);
        this.updateCacheOfShopSign(shopId);
        try {
            // 数据通讯
            JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.SHOP_SIGN_COMPANY_MODIFY)
                    .setLong01(shopId);
            JmsSender.setTopicSender(notify);
        } catch (Exception e) {
        }
    }

    public List<ShopSignCompanyInfo> listSignByShopId(Long shopId) {
        String key = null;
        List<ShopSignCompanyInfo> ll = shopSignMap.containsKey(key = getShopSignKey(shopId)) ? shopSignMap.get(key) : null;
        if (ll == null || ll.isEmpty()) {
            // 查询数据库
            String sql = "select * from " + PojoTables.SHOP_SIGN_COMPANY + " where delFlag=0 and status=" + SIGN_COMPANY_STATUS.pass + " and shopId=" + shopId;
            List<ShopSignCompanyInfo> list = null;
            try {
                list = (List<ShopSignCompanyInfo>) UserDaoSql.getInstance().list(ShopSignCompanyInfo.class, sql);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            if (list != null && !list.isEmpty()) {
                shopSignMap.put(key, list);
            }
            ll = list;
        }
        return ll;
    }

    private ShopSignCompanyFeeInfo get(List<ShopSignCompanyFeeInfo> list, int postType) {
        try {
            return list.stream().filter(a -> a.getPostType() == postType).findAny().get();
        } catch (Exception e) {
            return null;
        }
    }

    public void updateCacheOfShopSign(Long shopId) {
        shopSignMap.remove(getShopSignKey(shopId));
    }

    /******************商户和配送公司结算记录信息****************/
    // 商户和配送公司结算记录信息-添加
    public void addShopAndComJsRecords(ShopCompanyAccountRecords records) throws SQLException {
        UserDaoSql.getInstance().saveObj(PojoTables.SHOP_COMPANY_ACCOUNT_RECORDS, records);
    }

    // 商户和配送公司结算记录信息-列表查询

    private static String getShopSignKey(Long shopId) {
        return "shop_sign_" + shopId;
    }

    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        UserInfo user = null;
        user = new UserInfo().setId(1L);
        list.add(user);
        user = new UserInfo().setId(2L);
        list.add(user);
        user = null;
        for (int key = 0; key < list.size(); key++) {
            System.out.println(list.get(key));
        }
    }
}
